package net.towee.client.com.app.view;

import java.util.HashMap;
import java.util.Map;

import net.towee.client.com.app.AppController.Component;
import net.towee.client.com.app.presenter.TopPanelPresenter.Display;
import net.towee.client.i18n.ToweeConstants;
import net.towee.client.resources.ClientResource;
import net.towee.client.widgets.ListItemWidget;
import net.towee.client.widgets.UnorderedListWidget;

import com.google.gwt.animation.client.Animation;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;

/**
 * Implementation of top panel display logic.
 * 
 * @author c58
 */
public class TopPanelView extends UnorderedListWidget implements Display {
	/**
	 * Simple hide panel animation
	 * @author c58
	 */
	private class HideAnimation extends Animation {
		private final Widget w;
		private boolean showed = false;
		
		public HideAnimation(Widget w){
			this.w = w;
		}
		
		@Override
		public void onComplete() {
			super.onComplete();
			showed = !showed;
		}
		
		@Override
		protected void onUpdate(double progress) {
			progress = (showed)?progress:1-progress;
			w.getElement().getStyle().setProperty("top", ((-1)*44*progress)+"px");
			w.getElement().getStyle().setProperty("opacity", 1-progress+"");
		}
		
		public boolean isShowed(){
			return showed;
		}
	}
	
	private final ClientResource resource;
	private final ToweeConstants constants;
	
	private final Map<Component, ListItemWidget> buttonsMap;
	private final HideAnimation animation;
	private final int animationSpeed = 350;
	private Widget activeButton;

	@Inject
	public TopPanelView(ClientResource resource, ToweeConstants constants){
		this.constants = constants;
		this.resource = resource;
		this.buttonsMap = new HashMap<Component, ListItemWidget>();
		this.animation = new HideAnimation(this);
		
		// Set style
		setStyleName(resource.css().topPanelButtons());
		
		// Hide it
		getElement().getStyle().setProperty("top", "-44px");
		
		// Create buttons
		createButton(Component.ME, constants.me());
		createButton(Component.STUFF, constants.staff());
		createButton(Component.DASHBOARD, constants.dashboard() );
		createButton(Component.REPO, constants.reposetory() );
		createButton(Component.LOBBY, constants.lobby() );
	}

	private void createButton(Component com, String name) {
		ListItemWidget button = new ListItemWidget(name);
		button.setStyleName(resource.css().topPanelButton());
		buttonsMap.put(com, button);
	}
	
	private void addSeparator() {
		ListItemWidget button = new ListItemWidget();
		button.setStyleName(resource.css().topPanelSeparator());
		add(button);		
	}
	
	@Override
	public void selectComponent(Component com) {
		if(activeButton != null)
			activeButton.removeStyleName(resource.css().topPanelActiveButton());
		
		activeButton = buttonsMap.get( com );
		activeButton.addStyleName( resource.css().topPanelActiveButton() );
	}

	@Override
	public HasClickHandlers getMeButton() {
		return buttonsMap.get( Component.ME );
	}

	@Override
	public HasClickHandlers getStuffButton() {
		return buttonsMap.get( Component.STUFF );
	}

	@Override
	public HasClickHandlers getDashBoardButton() {
		return buttonsMap.get( Component.DASHBOARD );
	}

	@Override
	public HasClickHandlers getRepoButton() {
		return buttonsMap.get( Component.REPO );
	}

	@Override
	public void showMainButtons() {
		if(animation.isShowed()) {
			animation.run(animationSpeed);
			
			new Timer(){
				@Override
				public void run() {
					addMainButtons();
				}
			}.schedule(animationSpeed+10);
		}
		else
			addMainButtons();
	}
	
	private void addMainButtons() {
		clear();
		getElement().getStyle().setProperty("width", "429px");
		addSeparator();
		add(buttonsMap.get(Component.ME));
		addSeparator();
		add(buttonsMap.get(Component.STUFF));
		addSeparator();
		add(buttonsMap.get(Component.DASHBOARD));
		addSeparator();
		add(buttonsMap.get(Component.REPO));
		addSeparator();	
		animation.run(animationSpeed);
	}

	@Override
	public void showLobbyButton() {
		if(animation.isShowed()) {
			animation.run(animationSpeed);
			
			new Timer(){
				@Override
				public void run() {
					addLobbyButton();
				}
			}.schedule(animationSpeed+10);
		}
		else 
			addLobbyButton();
	}
	
	private void addLobbyButton(){
		clear();
		getElement().getStyle().setProperty("width", "108px");
		selectComponent(Component.LOBBY);
		addSeparator();
		add(buttonsMap.get(Component.LOBBY));
		addSeparator();
		animation.run(animationSpeed);
	}

}
